package com.wdm.sms.commonutil.config.inteceptor.jwt;

import cn.hutool.core.text.CharSequenceUtil;
import com.wdm.sms.commonutil.enums.ResponseEnum;
import com.wdm.sms.commonutil.config.exception.MyException;
import com.wdm.sms.commonutil.utils.jwt.PassToken;
import com.wdm.sms.commonutil.utils.jwt.JwtTokenUtils;
import com.wdm.sms.entity.common.dto.user.token.UserTokenDTO;
import com.wdm.sms.service.redis.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @author: wudaiming
 * @date: 2023/3/13
 * @description: 获取token并验证
 * @version: 1.0
 */

//@Component
@Slf4j
public class MyJwtInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisService redisService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String authToken = request.getHeader("token");
        String token;
        if (StringUtils.isNotEmpty(authToken)) {
            token = authToken.substring("".length() + 1).trim();
        } else{
            token="";
        }

        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        //检查是否通过有PassToken注解
        if (method.isAnnotationPresent(PassToken.class)) {
            //如果有则跳过认证检查
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) {
                return true;
            }
        }
        //否则进行token检查
        if (CharSequenceUtil.isBlank(token)) {
            throw new MyException(ResponseEnum.TOKEN_EX.getCode(), ResponseEnum.TOKEN_EX.getResultMessage());
        }
        UserTokenDTO userTokenDTO = JwtTokenUtils.parseToken(token);
        //1.判断请求是否有效
        if (redisService.get(userTokenDTO.getName()) == null
                || !redisService.get(userTokenDTO.getName()).equals(token)) {
            throw new MyException(ResponseEnum.TOKEN_EX);
        }

        //2.判断是否需要续期
        Long expireTime = redisService.getExpireTime(userTokenDTO.getName());
        if ( expireTime < 1 * 60 * 30) {
            redisService.set(userTokenDTO.getName(), token);
            log.error("update token info, id is:{}, user info is:{}", userTokenDTO.getName(), token);
        }
        return true;
    }
}